#include "MathVector.h"
#include <math.h>

MathVector::MathVector(){zero();}
MathVector::MathVector(const MathVector &v){set(v.getX(),v.getY(),getZ());}
MathVector::MathVector(double x,double y,double z){set(x,y,z);}
MathVector::~MathVector(){}
MathVector& MathVector::set(double x,double y,double z){
	this->x=x;
	this->y=y;
	this->z=z;
	return *this;
}
MathVector& MathVector::set(const MathVector &a){
	x=a.getX();
	y=a.getY();
	z=a.getZ();
	return *this;
}
MathVector& MathVector::setX(double x){this->x=x;return *this;}
MathVector& MathVector::setY(double x){this->y=y;return *this;}
MathVector& MathVector::setZ(double x){this->z=z;return *this;}
MathVector& MathVector::set(double vecAry[]){
    setX(vecAry[0]);
    setY(vecAry[1]);
    setZ(vecAry[2]);
    return *this;
}
double MathVector::getX() const{return x;}
double MathVector::getY() const{return y;}
double MathVector::getZ() const{return z;}
bool MathVector::eq(const MathVector &a) const{return x==a.getX()&&y==a.getY()&&x==a.getZ();}
bool MathVector::neq(const MathVector &a) const{return !neq(a);}
double MathVector::magnitude() const{return sqrt((x*x)+(y*y)+(z*z));}
double MathVector::length() const {return magnitude();}
MathVector& MathVector::zero(){x=0;y=0;z=0;return *this;}

//math
MathVector& MathVector::addSelf(const MathVector &a){
	x+=a.getX();
	y+=a.getY();
	z+=a.getZ();
	return *this;
}
MathVector MathVector::add(const MathVector &a) const{
	MathVector v(*this);
	v.addSelf(a);
	return v;
}
MathVector& MathVector::subSelf(const MathVector &a){
	x-=a.getX();
	y-=a.getY();
	z-=a.getZ();
	return *this;
}
MathVector MathVector::sub(const MathVector &a) const{
	MathVector v(*this);
	v.subSelf(a);
	return v;
}
MathVector& MathVector::multiplySelf(double a){
	x*=a;
	y*=a;
	z*=a;
	return *this;
}
MathVector MathVector::multiply(double a) const{
	MathVector v(*this);
	v.multiplySelf(a);
	return v;
}
MathVector& MathVector::divideSelf(double a){
	x/=a;
	y/=a;
	z/=a;
	return *this;
}
MathVector MathVector::divide(double a) const{
	MathVector v(*this);
	v.divide(a);
	return v;
}
MathVector& MathVector::dotSelf(const MathVector &a){
	x*=a.getX();
	y*=a.getY();
	z*=a.getZ();
	return *this;
}
MathVector MathVector::dot(const MathVector &a) const{
	MathVector v(*this);
	v.dotSelf(*this);
	return v;
}
MathVector& MathVector::crossSelf(const MathVector &a){
	double newX,newY,newZ;
	newX = (y * a.getZ()) - (z * a.getY());
	newY = (z * a.getX()) - (x * a.getZ());
	newZ = (x * a.getY()) - (y * a.getX());
	x=newX;y=newY;z=newZ;
	return *this;
}
MathVector MathVector::cross(const MathVector &a) const{
	MathVector v(*this);
	v.crossSelf(a);
	return v;
}

//operator overloads
MathVector& MathVector::operator+=(const MathVector &a){return addSelf(a);}
MathVector& MathVector::operator-=(const MathVector &a){return subSelf(a);}
MathVector& MathVector::operator*=(const MathVector &dotV){return dotSelf(dotV);}
MathVector& MathVector::operator*=(double magnitude){return multiplySelf(magnitude);}
MathVector& MathVector::operator/=(const MathVector &crossV){return crossSelf(crossV);}
MathVector& MathVector::operator/=(double magnitude){return divideSelf(magnitude);}
MathVector MathVector::operator+(const MathVector &a) const{return add(a);}
MathVector MathVector::operator-(const MathVector &a) const{return sub(a);}
MathVector MathVector::operator*(const MathVector &dotV) const{return dot(dotV);}
MathVector MathVector::operator*(double magnitude) const{return multiply(magnitude);}
MathVector MathVector::operator/(const MathVector &crossV) const{return cross(crossV);}
MathVector MathVector::operator/(double magnitude) const{return divide(magnitude);}
bool MathVector::operator==(const MathVector &a) const{return eq(a);}
bool MathVector::operator!=(const MathVector &a) const{return neq(a);}
